package com.boomkeeper.excel.rw;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Component;

import com.boomkeeper.archive.model.ArchiveDirctory;
import com.boomkeeper.core.model.ChangeOrder;
import com.boomkeeper.core.model.ChangeOrderData;
import com.boomkeeper.core.utils.DateUtils;

/**
 * 将Reader汇总的所有变更单数据写入汇总Excel，作为此次版本变更单汇总
 * @author zhangyu15
 *
 */
@Component
public class Writer {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(Writer.class);
	
	@Autowired
	private Reader reader;
	
	@Autowired
	private ArchiveDirctory archiveDirctory;
	
	@DateTimeFormat(pattern="yyyyMMdd")
	private String dateVersion;
	
	private Workbook workbook;
	
	private File excelFile;
	
	private List<ChangeOrder> changeOrderList;
	
	private List<String> publishInstructionList;
	
	/**
	 * 获取变更单数据
	 * @param changeOrderData
	 * @return
	 */
	public Writer initData(ChangeOrderData changeOrderData) {
		//归档archive已经拿到配置文件、war包等发布流程相关数据
		this.publishInstructionList = changeOrderData.getPublishInstructionList();
		List<ChangeOrder> tempList = changeOrderData.getChangeOrderList();
		//获取所有变更单数据
		tempList.addAll(reader.readFils().getData());
		this.changeOrderList = tempList;
		//现在writer拿到所有版本数据，可以调write()写入Excel
		return this;
	}

	/**
	 * 写入变更单数据到汇总Excel
	 */
	public void write() {
		try {
			this.excelFile = new File(archiveDirctory.getLteVersionPath() + "LTE-Portal-Version.xlsx");
			this.workbook = WorkbookFactory.create(this.excelFile);
			
			for (int i = 0, length = this.changeOrderList.size(); i < length; i++) {
				this.writeFirstSheet(this.changeOrderList.get(i), i);
				this.writeLastSheet(this.changeOrderList.get(i), i);
			}
			
			this.writeSecondSheet();
			this.renameExcelFile();
		} catch (EncryptedDocumentException | InvalidFormatException | IOException e) {
			LOGGER.error("创建excel reader时发生异常", e);
		}
	}
	
	private void writeFirstSheet(ChangeOrder changeOrder, int loopIndex) {
		int rowNum = loopIndex + 4;
		Sheet sheet = this.workbook.getSheetAt(0);
		Row row = sheet.getRow(rowNum);
		row.getCell(0).setCellValue(changeOrder.isBug() ? "Bug" : "需求");
		row.getCell(1).setCellValue(changeOrder.getRedmine());
		row.getCell(2).setCellValue(changeOrder.getSubject());
		row.getCell(3).setCellValue(changeOrder.getSubject());
		row.getCell(4).setCellValue(changeOrder.getAuthor());
		row.getCell(5).setCellValue(changeOrder.getReviewer());
		row.getCell(6).setCellValue(changeOrder.getDate());
		
		row = sheet.getRow(1);
		row.getCell(0).setCellValue(DateUtils.getDefaultDate());
	}
	
	private void writeSecondSheet() {
		Sheet sheet = this.workbook.getSheetAt(1);
		for (int i = 0, length = this.publishInstructionList.size(); i < length; i++) {
			Row row = sheet.getRow(i + 1);
			row.getCell(1).setCellValue(this.publishInstructionList.get(i));
		}
	}
	
	private void writeLastSheet(ChangeOrder changeOrder, int loopIndex) {
		int rowNum = loopIndex + 1;
		Sheet sheet = this.workbook.getSheetAt(3);
		Row row = sheet.getRow(rowNum);
		row.getCell(1).setCellValue(changeOrder.getChangeOrderFileName());
		row.getCell(2).setCellValue("是");
	}
	
	private void renameExcelFile() {
		LOGGER.debug("使用spring注解获得的日期：", this.dateVersion);
		this.dateVersion = DateUtils.getDefaultDate();
		File newNameExcelFile = new File(archiveDirctory.getLteVersionPath() + "LTE-Portal-" + this.dateVersion + "-Version-Description-Document.xlsx");
		this.excelFile.renameTo(newNameExcelFile);
		OutputStream os = null;
		try {
			 os = new FileOutputStream(newNameExcelFile);
			this.workbook.write(os);
		} catch (IOException e) {
			LOGGER.error("写入Excel文件异常", e);
		} finally {
			if (os != null) {
				try {
					os.flush();
					os.close();
				} catch (IOException e) {
					LOGGER.error("写入Excel文件完成，但关闭输出流异常", e);
				}
			}
		}
	}
}
